﻿//======================================================================
//
//	Cross-Platform XNA Menu System
//  http://cpxms.codeplex.com/
//
//  All code and content licensed under Microsoft Public License (Ms-PL)	
//
//======================================================================
//
//	File:		MainFrm.cs
//
//	Author:		MJP
//
//	Date:		04/12/09
//
//======================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;
using System.Reflection;
using System.Windows.Forms;
using System.Configuration;

using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

using CPXMenu;

using CPXMenuEditor.Controls;
using CPXMenuEditor.Properties;

using CPXMenuItem = CPXMenu.MenuItem;

namespace CPXMenuEditor.Forms
{
    public partial class MainFrm : Form
    {
        private ActionManager actionManager;
        private Clipboard clipboard;

        public static string TempProjectDirectory;
        public static string TempContentDirectory;
        public static string TempDefaultContentDirectory;
        public static string TempImportContentDirectory;
        public static string AppPath;        

        public const string AppName = "CPXMenu Editor";
        public const string FileExtension = "cpxm";
        public const string ExtensionFilter = "CPXMenu Project Files (*.cpxm)|*.cpxm";
        public const string DefaultContentDirectory = "CPXMenu Content";

        public MenuEditorView MenuEditorView
        {
            get { return menuEditorView; }
        }

        public MenuTree MenuTree
        {
            get { return menuTree; }
        }

        public StatusStrip StatusStrip
        {
            get { return statusStrip; }
        }

        public ItemProperties ItemProperties
        {
            get { return itemProperties; }
        }

        public HScrollBar HScrollBar
        {
            get { return hScrollBar; }
        }

        public VScrollBar VScrollBar
        {
            get { return vScrollBar; }
        }

        public ActionManager ActionManager
        {
            get { return actionManager; }
        }

        public Clipboard Clipboard
        {
            get { return clipboard; }
        }

        public MainFrm()
        {
            InitializeComponent();

            this.Text = AppName;
            TempProjectDirectory = Path.Combine(Path.GetTempPath(), AppName + "_" + Process.GetCurrentProcess().Id);
            TempContentDirectory = Path.Combine(TempProjectDirectory, "Content");
            TempDefaultContentDirectory = Path.Combine(MainFrm.TempContentDirectory, DefaultContentDirectory);
            TempImportContentDirectory = Path.Combine(MainFrm.TempContentDirectory, MenuProject.ImportedContentDirectoryName);
            AppPath = Path.GetDirectoryName(Application.ExecutablePath);

			InitalizeSettings();

            actionManager = new ActionManager(this);            

            actionManager.ActionOccurred += new ActionDelegate(actionManager_ActionOccurred);
            actionManager.UndoOccurred += new ActionDelegate(actionManager_UndoOccurred);
            actionManager.RedoOccurred += new ActionDelegate(actionManager_RedoOccurred);
            actionManager.ProjectClosing += new ProjectClosingDelegate(actionManager_ProjectClosing);
            actionManager.EnteringPreviewMode += new ActionManagerDelegate(actionManager_EnteringPreviewMode);
            actionManager.LeavingPreviewMode += new ActionManagerDelegate(actionManager_LeavingPreviewMode);
			actionManager.SelectionChanged += new ActionManagerDelegate(actionManager_SelectionChanged);
			actionManager.ProjectChanged += new ProjectChangedDelegate(actionManager_ProjectChanged);

            actionManager.CreateNewProject();
           
            clipboard = new Clipboard(actionManager);
            clipboard.MessageNeedsToBeShown += new ClipboardMessageDelegate(clipboard_MessageNeedsToBeShown);
			clipboard.ClipboardContentsChanged += new ClipboardDelegate(clipboard_ClipboardContentsChanged);

            menuEditorView.Initialize(this);
            menuTree.Initialize(this);
            itemProperties.Initialize(this);			
        }

		public void ShowMessage(string message, MessageBoxIcon icon)
		{
			MessageBox.Show(this, message, AppName, MessageBoxButtons.OK, icon);
		}
				
        public ContextMenuStrip GetContextMenuForItem(CPXMenuItem item)
        {
            ContextMenuStrip contextMenu = new ContextMenuStrip();
            contextMenu.ImageList = menuImages;

            if (item.CanHaveChildren)
                contextMenu.Items.Add(CreateContextItem(item, "Add Child Item", "New", addNewItem_Click));                

            if (!(item is MenuProject))
                contextMenu.Items.Add(CreateContextItem(item, "Delete Item", "Delete", delete_Click));

			if (item is Page)
				contextMenu.Items.Add(CreateContextItem(item, "Set As HomePage", "HomePage", setAsHomePage_Click));

            contextMenu.Items.Add(CreateContextItem(item, "Properties", "Properties", properties_Click));

            
            return contextMenu;
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);            

            if (MessageBox.Show(this, "Are you sure you want to exit?", AppName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                e.Cancel = true;
                return;
            }

            if (!actionManager.CloseProject())
            {
                e.Cancel = true;
                return;
            }            
        }

        private ToolStripMenuItem CreateContextItem(CPXMenuItem item, string text, string imageKey, EventHandler handler)
        {
            ToolStripMenuItem contextItem = new ToolStripMenuItem(text);
            contextItem.Click += handler;
            contextItem.Tag = item;
            contextItem.ImageKey = imageKey;
            return contextItem;
        }

		private void UpdateUndoRedo()
		{
			undoToolStripMenuItem.Enabled = actionManager.CanUndo;
			undoToolStripButton.Enabled = actionManager.CanUndo;
			redoToolStripMenuItem.Enabled = actionManager.CanRedo;
			redoToolStripButton.Enabled = actionManager.CanRedo;
		}

		private void InitalizeSettings()
		{

		}		

        private void addNewItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem contextItem = sender as ToolStripMenuItem;
            if (contextItem == null)
            {
                Debug.Assert(false);
                return;
            }

            CPXMenuItem menuItem = contextItem.Tag as CPXMenuItem;
            if (menuItem == null)
            {
                Debug.Assert(false);
                return;
            }

            AddNewItem addItemDialog = new AddNewItem(menuItem);
            if (addItemDialog.ShowDialog(this) == DialogResult.OK)
                actionManager.AddNewItem(addItemDialog.SelectedType, menuItem);
        }

        private void delete_Click(object sender, EventArgs e)
        {
			if (actionManager != null)
				actionManager.RemoveSelectedItems();
        }

        private void properties_Click(object sender, EventArgs e)
        {
            tabControl.SelectedTab = propertiesTabPage;
        }

		private void setAsHomePage_Click(object sender, EventArgs e)
		{
			ToolStripMenuItem contextItem = sender as ToolStripMenuItem;
			if (contextItem == null)
			{
				Debug.Assert(false);
				return;
			}

			Page page = contextItem.Tag as Page;
			if (page == null)
			{
				Debug.Assert(false);
				return;
			}

			page.ParentProject.HomePage = page;
		}

        

        void actionManager_RedoOccurred(ActionManager manager, IEditAction action)
        {
            UpdateUndoRedo();   
        }

        void actionManager_UndoOccurred(ActionManager manager, IEditAction action)
        {
            UpdateUndoRedo();
        }

        void actionManager_ActionOccurred(ActionManager manager, IEditAction action)
        {
            UpdateUndoRedo();
        }

        void actionManager_ProjectClosing(ActionManager manager, MenuProject project, ref bool cancel)
        {
            if (actionManager.Dirty)
            {
                DialogResult mbResult = MessageBox.Show(this, "The project has unsaved changes.  Would you like to save before closing it?",
                                                        MainFrm.AppName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);

                if (mbResult == DialogResult.Yes)
                    actionManager.SaveProject();
                else if (mbResult == DialogResult.Cancel)
                    cancel = true;                                                       
            }
        }

        void actionManager_EnteringPreviewMode(ActionManager manager)
        {
            menuTree.Enabled = false;
            itemProperties.Enabled = false;
            fileToolStripMenuItem.Enabled = false;            
            editToolStripMenuItem.Enabled = false;
            helpToolStripMenuItem.Enabled = false;
            // menuEditorView.Enabled = false;
            itemList.Enabled = false;
            tabControl.Enabled = false;
            splitContainer1.Enabled = false;
            splitContainer2.Enabled = false;
            settingsToolStripMenuItem.Enabled = false;

            exitPreviewModeToolStripMenuItem.Enabled = true;
            enterPreviewModeToolStripMenuItem.Enabled = false;
        }  

        void actionManager_LeavingPreviewMode(ActionManager manager)
        {
            menuTree.Enabled = true;
            itemProperties.Enabled = true;
            fileToolStripMenuItem.Enabled = true;
            editToolStripMenuItem.Enabled = true;
            helpToolStripMenuItem.Enabled = true;
            menuEditorView.Enabled = true;
            itemList.Enabled = true;
            tabControl.Enabled = true;
            splitContainer1.Enabled = true;
            splitContainer2.Enabled = true;
            settingsToolStripMenuItem.Enabled = true;

            exitPreviewModeToolStripMenuItem.Enabled = false;
            enterPreviewModeToolStripMenuItem.Enabled = true;
        }
		
		void actionManager_SelectionChanged(ActionManager manager)
		{
			bool enabled = actionManager.SelectedItems.Count > 0;
			deleteToolStripMenuItem.Enabled = enabled;
			copyToolStripButton.Enabled = enabled;
			copyToolStripMenuItem.Enabled = enabled;
			cutToolStripButton.Enabled = enabled;
			cutToolStripMenuItem.Enabled = enabled;
		}

		void actionManager_ProjectChanged(ActionManager manager, MenuProject oldProject, MenuProject newProject)
		{
			UpdateUndoRedo();

			bool enabled = newProject != null;
			saveAsToolStripMenuItem.Enabled = enabled;
			saveToolStripButton.Enabled = enabled;
			saveToolStripMenuItem.Enabled = enabled;
			enterPreviewModeToolStripMenuItem.Enabled = enabled;
			closeToolStripMenuItem.Enabled = enabled;
		}

		void clipboard_ClipboardContentsChanged(Clipboard clipboard)
		{
			pasteToolStripButton.Enabled = clipboard.ClipboardContents.Count > 0;
			pasteToolStripMenuItem.Enabled = pasteToolStripButton.Enabled;
		}

        void clipboard_MessageNeedsToBeShown(Clipboard clipboard, string message)
        {
			ShowMessage(message, MessageBoxIcon.Information);
        }

        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.Undo();
        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.Redo();
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clipboard.Cut();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clipboard.Copy();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            clipboard.Paste();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.CreateNewProject();
			
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (actionManager.PreviewMode)
                return;

            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.AddExtension = true;
            openFileDialog.Multiselect = false;
            openFileDialog.CheckFileExists = true;
            openFileDialog.Filter = ExtensionFilter;
            openFileDialog.DefaultExt = FileExtension;
            openFileDialog.ValidateNames = true;
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)            
                actionManager.OpenProject(openFileDialog.FileName);                       
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
			if (actionManager.MenuProject == null)
				return;

            if (actionManager.PreviewMode)
                return;

            if (string.IsNullOrEmpty(actionManager.ProjectFileName))
                saveAsToolStripMenuItem_Click(this, EventArgs.Empty);
            else
                actionManager.SaveProject();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
			if (actionManager.MenuProject == null)
				return;

            if (actionManager.PreviewMode)
                return;

            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.AddExtension = true;
            saveFileDialog.DefaultExt = FileExtension;
            saveFileDialog.Filter = ExtensionFilter;
            saveFileDialog.OverwritePrompt = true;
            saveFileDialog.ValidateNames = true;
            if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
                actionManager.SaveProjectAs(saveFileDialog.FileName);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void enterPreviewModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.EnterPreviewMode();
        }

        private void exitPreviewModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.ExitPreviewMode();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            actionManager.RemoveSelectedItems();
        }

		private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			AboutBox aboutBox = new AboutBox();
			aboutBox.ShowDialog(this);
		}		

		private void closeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			actionManager.CloseProject();
		}

        private void contentPipelineAssembliesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PipelineAssemblies dialog = new PipelineAssemblies();
            dialog.ShowDialog();
        }


    }
}
